import hcs.agi.proxy.AgiInstructionsHandler;
import hcs.agi.proxy.HttpChannel;
import org.asteriskjava.fastagi.AgiChannel;
import org.asteriskjava.fastagi.AgiException;
import org.asteriskjava.fastagi.AgiRequest;
import org.asteriskjava.fastagi.BaseAgiScript;
import org.asteriskjava.manager.ManagerConnection;
import org.asteriskjava.manager.ManagerConnectionFactory;
import org.asteriskjava.manager.action.RedirectAction;

import java.io.FileInputStream;
import java.util.Properties;
/*
 * AgiProxyScript.java
 * Created on 26.02.2008, 20:07
 */

/**
 * @author A.Ustinov
 */
public class AgiProxyScript extends BaseAgiScript {
    private AgiRequest agiRequest;
    private AgiChannel agiChannel;

    public void service(AgiRequest aGIRequest, AgiChannel aGIChannel) throws AgiException {
        //..create http-parameter string
        String tmpRequestString = createRequestString(aGIRequest);

        //..http-call and get instructions
        String tmpInstructions = "";
        try {
            tmpInstructions = HttpChannel.getInstructions(getPropertyValue("urltunnel", true), tmpRequestString);
        } catch (Exception ex) {
            processError(ex);
            return;
        }

        //..invoke instructions
        try {
            AgiInstructionsHandler.invokeInstructions(this, tmpInstructions);
        } catch (Exception ex) {
            processError(ex);
        }
    }

    //..call terminate

    public void terminate() throws AgiException {
        System.out.println("terminate");
        answer();
        hangup();
    }

    //..play media file

    public void playMediaFile(String aMediaFile) throws AgiException {
        System.out.println("playMediaFile " + aMediaFile);
        answer();
        streamFile(aMediaFile);
        hangup();
    }

    //..redirect call

    public void redirect(String aExten) throws AgiException {
        System.out.println("redirect to " + aExten);
        try {
            ManagerConnectionFactory factory = new ManagerConnectionFactory("localhost", "manager", "pa55w0rd"
//                    getPropertyValue("Connection-factory-hostname", true),
//                    getPropertyValue("Connection-factory-username", true),
//                    getPropertyValue("Connection-factory-password", true)
            );

            ManagerConnection managerConnection = factory.createManagerConnection();
            managerConnection.login();
            try {
                RedirectAction tmpRedirectAction = new RedirectAction(getAgiRequest().getChannel(), getAgiRequest().getContext(), aExten, 1);
                managerConnection.sendAction(tmpRedirectAction);
            } finally {
                managerConnection.logoff();
            }
        } catch (Exception ex) {
            throw new AgiException(ex.getMessage(), ex);
        }
    }

    public void recordCall(String aFileName) throws AgiException {
        System.out.println("call for recordCall in file with name " + aFileName);
        exec("MixMonitor", aFileName);
    }

    public void answer() throws AgiException {
        super.answer();
    }

    private static String getPropertyValue(String aPropertyName, boolean aRaise) throws Exception {
        Properties tmpProperties = new Properties();
        tmpProperties.load(new FileInputStream(System.getProperty("user.dir") + "/agiproxy.conf"));
        String tmpPropertyValue = tmpProperties.getProperty(aPropertyName);
        if ((tmpPropertyValue == null) || (tmpPropertyValue.isEmpty()) && (aRaise))
            throw new AgiException(aPropertyName + " is empty");
        return tmpPropertyValue;
    }

    private String createRequestString(AgiRequest aGIRequest) {
        return "CallerIdName=" + aGIRequest.getCallerIdName() + ";" +
                "CallerIdNumber=" + aGIRequest.getCallerIdNumber() + ";" +
                "Extension=" + aGIRequest.getExtension() + ";";
    }

    private void processError(Exception ex) {
        try {
            ex.printStackTrace();
            String tmpErrorMediaFile = getPropertyValue("errormediafile", false);
            if ((tmpErrorMediaFile != null) && (!tmpErrorMediaFile.isEmpty())) streamFile(tmpErrorMediaFile);
            hangup();
        } catch (Exception e) {
        }
    }

    private AgiRequest getAgiRequest() {
        return agiRequest;
    }

    private void setAgiRequest(AgiRequest agiRequest) {
        this.agiRequest = agiRequest;
    }

    private AgiChannel getAgiChannel() {
        return agiChannel;
    }

    private void setAgiChannel(AgiChannel agiChannel) {
        this.agiChannel = agiChannel;
    }
}
